<!DOCTYPE html>
<html>
  <!--
    Copyright 2010 Google Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
  -->
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="chrome=1">
    <title>Android Asset Studio - Icon Generator - Launcher icons</title>

    <link rel="stylesheet" href="lib/cssreset-3.4.1.min.css">
    <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:regular,medium,thin,italic,mediumitalic,bold" title="roboto">
    <link rel="stylesheet" href="css/studio.css">

    <script src="lib/jquery.min.js"></script>

    <!-- canvg used to work around <img src=SVG> toDataURL security issues -->
    <!-- see code.google.com/p/chromium/issues/detail?id=54204 -->
    <script src="lib/canvg/rgbcolor.js"></script> 
    <script src="lib/canvg/canvg.js"></script>

    <!-- prereq. for asset studio lib -->
    <link rel="stylesheet" href="lib/spectrum/spectrum-assetstudio.css">
    <script src="lib/spectrum/spectrum.js"></script>
    <script src="lib/jszip/jszip.js"></script>

    <script src="js/asset-studio.pack.js"></script>

    <!-- TODO: remove Analytics tracking if you're building the tools locally! -->
    <script type="text/javascript">
      var _gaq = _gaq || [];
      _gaq.push(['_setAccount', 'UA-18671401-1']);
      _gaq.push(['_trackPageview']);
      (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
      })();
    </script>
  </head>
  <body>
    <div id="main-container">
      <div id="page-header">
        <a href="index.html">Android Asset Studio</a>
        <h1>Launcher Icon Generator</h1>
      </div>
      <div id="inputs">
        <div id="inputs-form"></div>
      </div>
      <div id="outputs">
        <h3>
          <div id="zip-button-stub"></div>
          <button id="generate-web-button">Generate Web Icon</button>
        </h3>
      </div>
      <div id="footer">
        <p>Based on the launcher boilerplates from <a href="http://www.androidicons.com/">androidicons.com</a>, with permission.</p>
        <p>See the source at the <a href="http://code.google.com/p/android-ui-utils">android-ui-utils</a> Google Code project.</p>
        <p>All generated art is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>. <a href="attribution.html">Attribution info</a></p>
      </div>
    </div>

    <script>
      var DENSITIES = {'xxhdpi':1, 'xhdpi':1, 'hdpi':1, 'mdpi':1, 'web':1};

      $(studio.checkBrowser);
      imagelib.ALLOW_MANUAL_RESCALE = true;

      $('#generate-web-button').click(function() {
        regenerate(true, true);
      });

      var zipper = studio.zip.createDownloadifyZipButton($('#zip-button-stub'));

      // Create image output slots
      var group = studio.ui.createImageOutputGroup({
        container: $('#outputs'),
        dark: true
      });
      for (var density in DENSITIES)
        studio.ui.createImageOutputSlot({
          container: group,
          id: 'out-icon-' + density,
          label: (density == 'web') ? 'web, hi-res' : density
        });

      // Load image resources (stencils)
      var resList = {};
      for (var density in DENSITIES)
        for (var backgroundShape in {'square':1, 'circle':1})
          for (var type in {'back':1, 'fore1':1, 'mask':1, 'mask_inner':1})
            resList[backgroundShape + '-' + density + '-' + type] = (
              'res/launcher-stencil/' + backgroundShape + '/' + density + '/' + type + '.png');

      var IMAGE_RESOURCES = {};
      imagelib.loadImageResources(resList, function(r) {
        IMAGE_RESOURCES = r;
        IMAGE_RESOURCES._loaded = true;
        regenerate();
        studio.hash.bindFormToDocumentHash(form);
      });

      var PARAM_RESOURCES = {
         'web-iconSize': { w: 512, h: 512 },
        'hdpi-iconSize': { w:  72, h:  72 },
        'mdpi-iconSize': { w:  48, h:  48 },

         'web-none-targetRect': { x: 32, y: 32, w: 448, h: 448 },
        'hdpi-none-targetRect': { x:  4, y:  4, w:  64, h:  64 },
        'mdpi-none-targetRect': { x:  3, y:  3, w:  42, h:  42 },

         'web-circle-targetRect': { x: 32, y: 43, w: 448, h: 448 },
        'hdpi-circle-targetRect': { x:  4, y:  6, w:  64, h:  64 },
        'mdpi-circle-targetRect': { x:  3, y:  4, w:  42, h:  42 },

         'web-square-targetRect': { x: 32, y: 53, w: 448, h: 427 },
        'hdpi-square-targetRect': { x:  4, y:  8, w:  64, h:  60 },
        'mdpi-square-targetRect': { x:  3, y:  5, w:  42, h:  40 }
      };

      /**
       * Main image generation routine.
       */
      function regenerate(force, generateWebIcon) {
        if (!force) {
          if (regenerate.timeout_) {
            clearTimeout(regenerate.timeout_);
          }
          regenerate.timeout_ = setTimeout(function() {
            regenerate(true);
          }, 1000);
          return;
        }

        if (!IMAGE_RESOURCES._loaded)
          return;

        var values = form.getValues();

        var iconName = 'ic_launcher';
        zipper.clear();
        zipper.setZipFilename(iconName + '.zip');

        var continue_ = function(foreCtx) {
          var backgroundShape = values['backgroundShape'];
          for (var density in DENSITIES) {
            var mult = studio.util.getMultBaseMdpi(density);
            if (density == 'web') {
              mult = 1;
              if (!generateWebIcon) {
                continue;
              }
            }

            var mult = studio.util.getMultBaseMdpi(density);
            var iconSize = PARAM_RESOURCES[density + '-iconSize']
                || studio.util.multRound(PARAM_RESOURCES['mdpi-iconSize'], mult);
            var targetRect = PARAM_RESOURCES[density + '-' + backgroundShape + '-targetRect']
                || studio.util.multRound(PARAM_RESOURCES['mdpi-' + backgroundShape + '-targetRect'],
                   mult);

            var outCtx = imagelib.drawing.context(iconSize);
            var tmpCtx = imagelib.drawing.context(iconSize);

            if (backgroundShape == 'none') {
              tmpCtx.save();
              tmpCtx.globalCompositeOperation = 'source-over';
              if (foreCtx) {
                var copyFrom = foreCtx;
                var foreSize = {
                  w: foreCtx.canvas.width,
                  h: foreCtx.canvas.height
                };

                if (values['foreColor'].alpha) {
                  var tmpCtx2 = imagelib.drawing.context(foreSize);
                  imagelib.drawing.copy(tmpCtx2, foreCtx, foreSize);
                  tmpCtx2.globalCompositeOperation = 'source-atop';
                  tmpCtx2.fillStyle = values['foreColor'].color;
                  tmpCtx2.fillRect(0, 0, foreSize.w, foreSize.h);
                  copyFrom = tmpCtx2;
                  tmpCtx.globalAlpha = values['foreColor'].alpha / 100;
                }

                imagelib.drawing[values['crop'] ? 'drawCenterCrop' : 'drawCenterInside']
                  (tmpCtx, copyFrom, targetRect, {
                    x: 0, y: 0,
                    w: foreSize.w, h: foreSize.h
                  });
              }
              tmpCtx.restore();

              var foreEffect = 1; //values['foreEffect'];

              if (density == 'web') {
                imagelib.drawing.fx([
                  {
                    effect: 'inner-shadow',
                    color: '#fff',
                    opacity: 0.25,
                    blur: 0,
                    translate: { y: 5 }
                  },
                  {
                    effect: 'inner-shadow',
                    color: '#000',
                    opacity: 0.4,
                    blur: 5,
                    translate: { y: -5 }
                  },
                  {
                    effect: 'outer-shadow',
                    color: '#000',
                    opacity: 0.4,
                    blur: 8,
                    translate: { y: 3 }
                  }
                ], outCtx, tmpCtx, iconSize);

              } else {
                imagelib.drawing.fx([
                  {
                    effect: 'inner-shadow',
                    color: '#fff',
                    opacity: 0.25,
                    blur: 0,
                    translate: { y: Math.ceil(0.5 * mult) }
                  },
                  {
                    effect: 'inner-shadow',
                    color: '#000',
                    opacity: 0.6,
                    blur: Math.ceil(1 * mult),
                    translate: { y: -Math.ceil(0.5 * mult) }
                  },
                  {
                    effect: 'outer-shadow',
                    color: '#000',
                    opacity: 0.3,
                    blur: Math.ceil(2 * mult),
                    translate: { y: Math.ceil(0.5 * mult) }
                  }
                ], outCtx, tmpCtx, iconSize);
              }

            } else {
              tmpCtx.save();
              tmpCtx.globalCompositeOperation = 'source-over';
              imagelib.drawing.copy(tmpCtx, IMAGE_RESOURCES[backgroundShape + '-' + density + '-mask'], iconSize);
              tmpCtx.globalCompositeOperation = 'source-atop';
              tmpCtx.fillStyle = values['backColor'].color;
              tmpCtx.fillRect(0, 0, iconSize.w, iconSize.h);

              if (foreCtx) {
                var tmpCtx2 = imagelib.drawing.context(iconSize);
                tmpCtx2.save();
                tmpCtx2.globalCompositeOperation = 'source-over';
                imagelib.drawing.copy(tmpCtx2, IMAGE_RESOURCES[backgroundShape + '-' + density + '-mask_inner'], iconSize);
                tmpCtx2.globalCompositeOperation = 'source-atop';
                tmpCtx2.fillStyle = values['backColor'].color;
                tmpCtx2.fillRect(0, 0, iconSize.w, iconSize.h);

                var copyFrom = foreCtx;
                var foreSize = {
                  w: foreCtx.canvas.width,
                  h: foreCtx.canvas.height
                };

                if (values['foreColor'].alpha) {
                  var tmpCtx3 = imagelib.drawing.context(foreSize);
                  imagelib.drawing.copy(tmpCtx3, foreCtx, foreSize);
                  tmpCtx3.globalCompositeOperation = 'source-atop';
                  tmpCtx3.fillStyle = values['foreColor'].color;
                  tmpCtx3.fillRect(0, 0, foreSize.w, foreSize.h);
                  copyFrom = tmpCtx3;
                  tmpCtx.globalAlpha = values['foreColor'].alpha / 100;
                }

                imagelib.drawing[values['crop'] ? 'drawCenterCrop' : 'drawCenterInside']
                  (tmpCtx2, copyFrom, targetRect, {
                    x: 0, y: 0,
                    w: foreSize.w, h: foreSize.h
                  });

                imagelib.drawing.copy(tmpCtx, tmpCtx2, iconSize);
              }
              tmpCtx.restore();

              var foreEffect = 1; //values['foreEffect'];
              imagelib.drawing.copy(outCtx, IMAGE_RESOURCES[backgroundShape + '-' + density + '-back'], iconSize);
              imagelib.drawing.copy(outCtx, tmpCtx, iconSize);
              imagelib.drawing.copy(outCtx, IMAGE_RESOURCES[backgroundShape + '-' + density + '-fore' + foreEffect], iconSize);
            }

            zipper.add({
              name: (density == 'web') ?
                  ('web_hi_res_512.png') :
                  ('res/drawable-' + density + '/ic_launcher.png'),
              base64data: outCtx.canvas.toDataURL().match(/;base64,(.+)/)[1]
            });

            imagelib.loadFromUri(outCtx.canvas.toDataURL(), function(density) {
              return function(img) {
                $('#out-icon-' + density).attr('src', img.src);
              };
            }(density));
          }
        };

        if (values['foreground']) {
          continue_(values['foreground'].ctx);
        } else {
          continue_(null);
        }
      }

      var form = new studio.forms.Form('iconform', {
        onChange: function(field) {
          regenerate();
        },
        fields: [
          new studio.forms.ImageField('foreground', {
            title: 'Foreground',
            defaultValueTrim: 1
          }),
          new studio.forms.ColorField('foreColor', {
            title: 'Color',
            helpText: 'For transparent foregrounds',
            defaultValue: '#33b5e5',
            alpha: true,
            defaultAlpha: 0
          }),
          new studio.forms.BooleanField('crop', {
            title: 'Scaling',
            defaultValue: false,
            offText: 'Center',
            onText: 'Crop'
          }),
          new studio.forms.EnumField('backgroundShape', {
            title: 'Shape',
            buttons: true,
            options: [
              { id: 'none', title: 'None' },
              { id: 'square', title: 'Square' },
              { id: 'circle', title: 'Circle' }
            ],
            defaultValue: 'none'
          }),
          new studio.forms.ColorField('backColor', {
            title: 'Background',
            defaultValue: '#ffffff'
          })
          // new studio.forms.EnumField('recenter', {
          //   title: 'Recentering',
          //   helpText: 'Recenters the icon based on its mass',
          //   buttons: true,
          //   options: [
          //     { id: 'none', title: 'None' },
          //     { id: 'horz', title: 'Horizontal' },
          //     { id: 'vert', title: 'Vertical' },
          //     { id: 'both', title: 'Both' }
          //   ],
          //   defaultValue: 'none'
          // })
          /*,new studio.forms.EnumField('foreEffect', {
            title: 'Foreground effects',
            buttons: true,
            options: [
              { id: '1', title: 'Simple' },
              { id: '2', title: 'Fancy' },
              { id: '3', title: 'Glossy' }
            ],
            defaultValue: '1'
          })*/
        ]
      });
      form.createUI($('#inputs-form').get(0));
    </script>
  </body>
</html>
